package com.feicheng.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feicheng.common.constant.Constant;
import com.feicheng.common.mqtt.*;
import com.feicheng.common.task.Cache;
import com.feicheng.common.util.DateUtils;
import com.feicheng.persistence.entity.Amj;
import com.feicheng.persistence.entity.Askjl;
import com.feicheng.persistence.entity.Ayyjlitem;
import com.feicheng.persistence.entity.Client;
import com.feicheng.persistence.service.*;
import com.feicheng.service.a.FMjService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;


@Slf4j
@Service
public class FMjConnectionService {

    @Autowired
    Cache cache;

    @Autowired
    FMjService mjService;

    @Autowired
    IClientService clientService;

    @Autowired
    IAskjlService askjlService;

    @Autowired
    MqttOutboundChannel mqttOutboundChannel;

    public void cmdDeleteAllPerson(String sn) {
        String topic = "mqtt/face/"+sn;
        MqttCmd cmd = MsgFactory.deleteAllPerson(sn);
        mqttOutboundChannel.sendMessage(topic, cmd.toJSONString());
    }

    public void cmdDelPerson(String sn, String customId) {
        String topic = "mqtt/face/"+sn;
        MqttCmd cmd = MsgFactory.delPerson(sn, customId);
        mqttOutboundChannel.sendMessage(topic, cmd.toJSONString());
    }

    public void cmdAddPersons(String sn, JSONArray info) {
        String topic = "mqtt/face/"+sn;
        MqttCmd cmd = MsgFactory.addPersons(sn, info);
        mqttOutboundChannel.sendMessage(topic, cmd.toJSONString());
    }

    public void cmdUnlock(String sn) {
        String topic = "mqtt/face/"+sn;
        MqttCmd cmd = MsgFactory.unLock(sn);
        cmd.getInfoObject().put("openDoor", 1);
        mqttOutboundChannel.sendMessage(topic, cmd.toJSONString());
    }

    private JSONObject createDzFace(String sn, String dzid, String dname, String tx) {
        return new MqttCmd.Person()
                .customId(dzid)
                .name(dname)
                .picURI(tx)
                .tempCardType(0).build();
    }

    private JSONObject createMdjlFace(String sn, String mdjlid, String mdjlname, String tx) {
        return new MqttCmd.Person()
                .customId(mdjlid)
                .name(mdjlname)
                .picURI(tx)
                .tempCardType(0).build();
    }

    private JSONObject createJlFace(String sn, String jlid, String jlname, String jltx, String cardValidBegin, String cardValidEnd) {
        return new MqttCmd.Person()
                .customId(jlid)
                .name(jlname)
                .picURI(jltx)
                .tempCardType(1)
                .cardValidBegin(cardValidBegin)
                .cardValidEnd(cardValidEnd)
                .build();
    }

    private JSONObject createXyFace(String sn, String xyid, String xyname, String xytx, String cardValidBegin, String cardValidEnd) {
        return new MqttCmd.Person()
                .customId(xyid)
                .name(xyname)
                .picURI(xytx)
                .tempCardType(1)
                .cardValidBegin(cardValidBegin)
                .cardValidEnd(cardValidEnd)
                .build();
    }


    /**
     * 删除所有设备所有人脸，会导致设备重启上线
     */
    private void clearAllMenjin() {
        cache.initMenjin();
        List<JSONObject> mjs = mjService.allMjByStoreAndRoom(new JSONObject());
        for (JSONObject mj : mjs) {
            // 删除设备所有人脸，会导致设备重启上线
            this.cmdDeleteAllPerson(mj.getString("sn"));
            cache.putMenjin(mj);
        }
    }


    public void runDzDailyTask() {

//        MqttCmd.IDS.clear();

        // 初始化所有门禁人脸名单
        this.clearAllMenjin();

    }

    public void loadSkjlsToMenjin() {
        QueryWrapper<Askjl> askjlqw = new QueryWrapper<>();
        String rq = LocalDate.now().format(Constant.yyyyMMdd);
        askjlqw.eq("rq", rq);
        List<Askjl> skjls = askjlService.list(askjlqw);
        this.addFaceToMjBySkjls(skjls);
    }

    /**
     * 门禁上线时调用
     * 找到门禁对用日期的所有人脸并添加到设备中
     * @param sn 设备序列号
     */
    public void addFaceToMenjin(String sn) {

        JSONArray faces = new JSONArray();

        // 从缓存中取得门禁
        JSONObject mj = cache.getMenjin(sn);

        //添加店长人脸
        if (StringUtils.hasLength(mj.getString("tx"))) {
            faces.add(this.createDzFace(sn, mj.getString("dzid"), mj.getString("mdmc"), mj.getString("tx")));
        }

        String mdid = mj.getString("mdid");

        JSONObject param = new JSONObject();
        param.put("rq", DateUtils.dateToString("yyyy-MM-dd", LocalDate.now()));
        param.put("st", "00:00:00");
        param.put("et", "23:59:59");
        param.put("mdid", mdid);
        JSONArray status = new JSONArray();
        status.add("U");
        status.add("R");
        param.put("status", status);
        List<JSONObject> clients = mjService.getYyclient(param);
        if (null != clients && clients.size() > 0) {
            clients.forEach(client -> {
                String rq = client.getString("arq");
                String st = rq + " " + client.getString("ast") + ":00";
                String et = rq + " " + client.getString("aet") + ":00";
                faces.add(this.createJlFace(sn, client.getString("clientid"), client.getString("nc"), client.getString("tx"), st, et));
            });
        }

        this.cmdAddPersons(sn, faces);

        this.loadSkjlsToMenjin();
    }

    public void addSingelFaceToMenjin(String sn, JSONObject yyjlitemObj) {
        JSONArray faces = new JSONArray();
        String rq = yyjlitemObj.getString("arq");
        String st = rq + " " + yyjlitemObj.getString("ast") + ":00";
        String et = rq + " " + yyjlitemObj.getString("aet") + ":00";
        faces.add(this.createJlFace(sn, yyjlitemObj.getString("clientid"), yyjlitemObj.getString("nc"), yyjlitemObj.getString("tx"), st, et));
        this.cmdAddPersons(sn, faces);
    }

    public void addSingelFacetoMdmj(Ayyjlitem ayyjlitem) {
        JSONObject param = new JSONObject();
        Client client = clientService.getById(ayyjlitem.getClientid());
        if (StringUtils.hasLength(client.getTx())) {
            param.put("mdid", ayyjlitem.getMdid());
            List<JSONObject> amjs = mjService.allMjByStoreAndRoom(param);

            if (null != amjs && amjs.size() > 0) {
                amjs.forEach(obj -> {
                    JSONArray faces = new JSONArray();
                    String rq = ayyjlitem.getRq().format(Constant.yyyyMMdd);
                    String st = rq + " " + ayyjlitem.getSt().format(Constant.HHmmss);
                    String et = rq + " " + ayyjlitem.getEt().format(Constant.HHmmss);
                    faces.add(this.createJlFace(obj.getString("sn"), ayyjlitem.getClientid(), client.getNc(), client.getTx(), st, et));
                    this.cmdAddPersons(obj.getString("sn"), faces);
                });
            }
        }
    }

    public void removeFaceToMjBySkjl(Askjl skjl) {
        JSONObject mdwithmj = cache.getMdWithmj().getJSONObject(skjl.getMdid());
        JSONArray mdsns = mdwithmj.getJSONArray("mdsns");

        for (int index = 0; index < mdsns.size(); index++) {
            String sn = mdsns.getString(index);
            this.cmdDelPerson(sn, skjl.getSkjlid());
        }

        JSONObject fjsnObj = mdwithmj.getJSONObject("fjObj");
        if (null != fjsnObj) {
            JSONArray fjsns = fjsnObj.getJSONArray(skjl.getFjid());
            if (null != fjsns) {
                for (int fndex = 0; fndex < fjsns.size(); fndex++) {
                    String snfj = fjsns.getString(fndex);
                    this.cmdDelPerson(snfj, skjl.getSkjlid());
                }
            }
        }

    }

    public void addFaceToMjBySkjl(Askjl skjl) {
        String rq = skjl.getRq().format(Constant.yyyyMMdd);
        String st = rq + " " + skjl.getSt().format(Constant.HHmmss);
        String et = rq + " " + skjl.getEt().format(Constant.HHmmss);

        JSONArray faces = new JSONArray();
        faces.add(this.createJlFace("sn", skjl.getSkjlid(), skjl.getMc(), skjl.getTx(), st, et));

        JSONObject mdwithmj = cache.getMdWithmj().getJSONObject(skjl.getMdid());
        JSONArray mdsns = mdwithmj.getJSONArray("mdsns");

        for (int index = 0; index < mdsns.size(); index++) {
            String sn = mdsns.getString(index);
            this.cmdAddPersons(sn, faces);
        }

        JSONObject fjsnObj = mdwithmj.getJSONObject("fjObj");
        if (null != fjsnObj) {
            JSONArray fjsns = fjsnObj.getJSONArray(skjl.getFjid());
            if (null != fjsns) {
                for (int fndex = 0; fndex < fjsns.size(); fndex++) {
                    String snfj = fjsns.getString(fndex);
                    this.cmdAddPersons(snfj, faces);
                }
            }
        }

    }

    public void addFaceToMjBySkjls(List<Askjl> askjls) {
        JSONObject mdwithface = new JSONObject();
        if (null != askjls && askjls.size() > 0) {
            askjls.forEach(skjl -> {

                String rq = skjl.getRq().format(Constant.yyyyMMdd);
                String st = rq + " " + skjl.getSt().format(Constant.HHmmss);
                String et = rq + " " + skjl.getEt().format(Constant.HHmmss);

                if (!mdwithface.containsKey(skjl.getMdid())) {
                    JSONObject md = new JSONObject();
                    JSONObject fjObj = new JSONObject();
                    md.put("faces", new JSONArray());
                    md.put("fjObj", fjObj);
                    mdwithface.put(skjl.getMdid(), md);
                }
                JSONObject md = mdwithface.getJSONObject(skjl.getMdid());
                JSONArray mdfaces = md.getJSONArray("faces");
                mdfaces.add(this.createJlFace("sn", skjl.getSkjlid(), skjl.getMc(), skjl.getTx(), st, et));

                JSONObject fjObj = md.getJSONObject("fjObj");
                if (StringUtils.hasLength(skjl.getFjid())) {
                    if (!fjObj.containsKey(skjl.getFjid())) {
                        fjObj.put(skjl.getFjid(), new JSONArray());
                    }
                    JSONArray fjfaces = fjObj.getJSONArray(skjl.getFjid());
                    fjfaces.add(this.createJlFace("sn", skjl.getSkjlid(), skjl.getMc(), skjl.getTx(), st, et));
                }
            });

            for (Iterator<String> it = mdwithface.keySet().iterator(); it.hasNext();) {
                String mdid = it.next();
                JSONObject md = mdwithface.getJSONObject(mdid);
                JSONArray mdfaces = md.getJSONArray("faces");
                JSONObject mdwithmj = cache.getMdWithmj().getJSONObject(mdid);
                JSONArray mdsns = mdwithmj.getJSONArray("mdsns");
                for (int index = 0; index < mdsns.size(); index++) {
                    String sn = mdsns.getString(index);
                    this.cmdAddPersons(sn, mdfaces);
                }
                JSONObject fjObj = md.getJSONObject("fjObj");

                for (Iterator<String> itfjid = fjObj.keySet().iterator(); itfjid.hasNext();) {
                    String fjid = itfjid.next();
                    JSONArray fjfaces = fjObj.getJSONArray(fjid);

                    JSONObject fjsnObj = mdwithmj.getJSONObject("fjObj");
                    if (null != fjsnObj) {
                        JSONArray fjsns = fjsnObj.getJSONArray(fjid);
                        if (null != fjsns) {
                            for (int fndex = 0; fndex < fjsns.size(); fndex++) {
                                String snfj = fjsns.getString(fndex);
                                this.cmdAddPersons(snfj, fjfaces);
                            }
                        }
                    }
                }

            }


        }
    }



}
